package org.xxpay.pay.channel.jeepay;

import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.Jeepay;
import com.jeequan.jeepay.JeepayClient;
import com.jeequan.jeepay.exception.JeepayException;
import com.jeequan.jeepay.model.PayOrderCreateReqModel;
import com.jeequan.jeepay.model.PayOrderQueryReqModel;
import com.jeequan.jeepay.request.PayOrderCreateRequest;
import com.jeequan.jeepay.request.PayOrderQueryRequest;
import com.jeequan.jeepay.response.PayOrderCreateResponse;
import com.jeequan.jeepay.response.PayOrderQueryResponse;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.xxpay.core.common.constant.PayConstant;
import org.xxpay.core.common.domain.api.AbstractRes;
import org.xxpay.core.common.domain.api.ApiBuilder;
import org.xxpay.core.common.domain.api.PayRes;
import org.xxpay.core.common.domain.api.msg.QueryRetMsg;
import org.xxpay.core.common.util.MyLog;
import org.xxpay.core.common.util.PayDigestUtil;
import org.xxpay.core.common.util.XXPayUtil;
import org.xxpay.core.common.vo.DBApplicationConfig;
import org.xxpay.core.entity.PayOrder;
import org.xxpay.pay.channel.BasePayment;
import org.xxpay.pay.channel.xxpay.XxpayConfig;

import java.util.Map;
import java.util.TreeMap;

/**
 * @description: jeepay
 */
@Service
public class JeepayPaymentService extends BasePayment {

    private static final MyLog _log = MyLog.getLog(JeepayPaymentService.class);

    @Override
    public String getChannelName() {
        return JeepayConfig.CHANNEL_NAME;
    }

    /**
     * 支付
     * @param payOrder
     * @return
     */
    @Override
    public AbstractRes pay(PayOrder payOrder) {
        _log.info("处理["+ JeepayConfig.CHANNEL_NAME+"]渠道支付业务, payOrderId={}, channelId={}", payOrder.getPayOrderId(), payOrder.getChannelId());
        String channelId = payOrder.getChannelId();
        String productId = channelId.substring(channelId.indexOf("_")+1);
        return doPay(payOrder, productId);
    }

    private AbstractRes doPay(PayOrder payOrder, String wayCode) {

        JeepayConfig jeepayConfig = new JeepayConfig(getPayParam(payOrder));
        PayRes retObj = ApiBuilder.buildSuccess(PayRes.class);
        DBApplicationConfig dbConfig = getDBApplicationConfig();

        // 创建客户端
        JeepayClient jeepayClient = new JeepayClient(jeepayConfig.getReqUrl(), jeepayConfig.getAppKey());

        // 构建请求数据
        PayOrderCreateRequest request = new PayOrderCreateRequest();
        PayOrderCreateReqModel model = new PayOrderCreateReqModel();
        model.setMchNo(jeepayConfig.getMchNo());             // 商户号
        model.setAppId(jeepayConfig.getAppId());             // 应用ID
        String orderNo = payOrder.getPayOrderId();
        model.setMchOrderNo(orderNo);                       // 商户订单号
        model.setWayCode(wayCode.toUpperCase());            // 支付方式
        model.setAmount(payOrder.getAmount());              // 金额，单位分
        model.setCurrency("cny");                           // 币种，目前只支持cny
        model.setClientIp(payOrder.getClientIp());          // 发起支付请求客户端的 IP 地址，格式为 IPV4，如: 127.0.0.1
        model.setSubject(payOrder.getSubject());            // 商品标题
        model.setBody(payOrder.getBody());                  // 商品描述
        model.setNotifyUrl(super.getNotifyUrl(getChannelName(), dbConfig));      // 异步通知地址
        model.setReturnUrl(super.getReturnUrl(getChannelName(), dbConfig));      // 前端跳转地址
        model.setChannelExtra(channelExtra(payOrder, wayCode));       // 渠道扩展参数
        model.setExtParam("");                              // 商户扩展参数,会掉时原样返回
        request.setBizModel(model);

        PayOrderCreateResponse response;
        // 发起统一下单
        try {
            response = jeepayClient.execute(request);
        } catch (JeepayException e) {
            _log.error("请求" + JeepayConfig.CHANNEL_NAME + "下单异常", e);
            return ApiBuilder.bizError("请求渠道支付异常");
        }
        if(response == null) {
            _log.error("请求" + JeepayConfig.CHANNEL_NAME + "下单返回为空");
            return ApiBuilder.bizError("请求渠道支付返回为空");
        }

        // 验证返回数据签名
        if(!response.checkSign(jeepayConfig.getAppKey())) {
            _log.error("请求["+ JeepayConfig.CHANNEL_NAME+"]下单返回数据验签失败");
            return ApiBuilder.bizError("请求渠道支付验签失败");
        }
        if(!response.isSuccess(jeepayConfig.getAppKey())) {
            _log.error("请求["+ JeepayConfig.CHANNEL_NAME+"]下单返回失败,msg={}", response.getMsg());
            return ApiBuilder.bizError("渠道返回[" + response.getMsg() + "]");
        }

        String payData = response.get().getPayData();
        int updateCount = commonService.payOrderService.updateStatus4Ing(payOrder.getPayOrderId(), response.get().getPayOrderId());
        _log.info("[{}]更新订单状态为支付中:payOrderId={},result={}", getChannelName(), payOrder.getPayOrderId(), updateCount);

        retObj.setPayJumpUrl(payData);      // 可以通过该地址跳转到支付中心界面完成支付(URL)
        StringBuffer payForm = new StringBuffer();
        payForm.append("<script>window.location.href = '"+payData+"';</script>");

        retObj.setPayUrl(payForm.toString());
        retObj.setPayMethod(PayConstant.PAY_METHOD_FORM_JUMP);

        return retObj;

    }

    /**
     * 查询订单
     * @param payOrder
     * @return
     */
    @Override
    public QueryRetMsg query(PayOrder payOrder) {
        JeepayConfig jeepayConfig = new JeepayConfig(getPayParam(payOrder));
        JeepayClient jeepayClient = new JeepayClient(jeepayConfig.getReqUrl(), jeepayConfig.getAppKey());
        PayOrderQueryRequest request = new PayOrderQueryRequest();
        PayOrderQueryReqModel model = new PayOrderQueryReqModel();
        model.setMchNo(jeepayConfig.getMchNo());                                  // 商户号
        model.setAppId(jeepayConfig.getAppId());
        model.setMchOrderNo(payOrder.getPayOrderId());                            // 商户订单号
        request.setBizModel(model);
        try {
            PayOrderQueryResponse response = jeepayClient.execute(request);
            if(!response.isSuccess(jeepayConfig.getAppKey())) {
                _log.error("请求["+JeepayConfig.CHANNEL_NAME+"]返回结果校验不过,code={}", response.getCode());
                return QueryRetMsg.waiting();  //支付中
            }
            int state = response.get().getState();
            // todo 如果订单退款了会有问题
            if(2 == state) {
                return QueryRetMsg.confirmSuccess(null);  // 成功
            }
        } catch (JeepayException e) {
            _log.error(e, "");
        }
        return QueryRetMsg.waiting();  //支付中
    }

    String channelExtra(PayOrder payOrder, String wayCode) {
        wayCode = wayCode.toUpperCase();
        JSONObject obj = new JSONObject();
        if("WX_JSAPI".equals(wayCode)) {
            obj.put("openId", payOrder.getChannelUser());
            return obj.toString();
        }
        if("ALI_JSAPI".equals(wayCode)) {
            obj.put("buyerUserId", payOrder.getChannelUser());
            return obj.toString();
        }
        if("WX_BAR".equals(wayCode) || "ALI_BAR".equals(wayCode) || "AUTO_BAR".equals(wayCode) || "YSF_BAR".equals(wayCode)) {
            obj.put("authCode", payOrder.getExtra());
            return obj.toString();
        }
        if("QR_CASHIER".equals(wayCode) || "ALI_QR".equals(wayCode) || "WX_NATIVE".equals(wayCode)) {
            obj.put("payDataType", "codeImgUrl");
            return obj.toString();
        }
        return "";
    }

}
